#include <proxy/proxy.hpp>

namespace udp_proxy {
Proxy::Proxy(){

}


Proxy::~Proxy(){

}

/**
 * @brief 连接
 * 连接所有的UDP实例并配置转发对
 *
 */
void Proxy::connect(){
    if (cfg_list.size() > 0){
        for(auto pair : cfg_list){
            std::cout << "connection info:" << std::endl;
            std::cout << "in" << std::endl;
            std::cout << pair.in;
            std::cout << "out" << std::endl;
            std::cout << pair.out;
            pair.udp_in->connect(std::bind(&ConnUdp::send_data, pair.udp_out, std::placeholders::_1, std::placeholders::_2));
            pair.udp_out->connect(std::bind(&ConnUdp::send_data, pair.udp_in, std::placeholders::_1, std::placeholders::_2));
        }
    }
}


void Proxy::load_config(std::string cfg_file){
    std::string s;
    _fs.open(cfg_file.c_str());

    int parse_flag = 0;
    while(std::getline(_fs, s)){
        ConnectPair pair;
        // std::cout << s << std::endl;
        if(s.find("[")!=std::string::npos && s.find("]")!=std::string::npos){
            parse_flag = 1;
        }
        if(parse_flag==1 && s.find("in:") != std::string::npos){ // 解析in配置
            UdpConfig cfg;
            try{
                std::istringstream iss(s.substr(std::string("in:").length()));
                iss >> cfg.local_host;
                iss >> cfg.local_port;
                iss >> cfg.remote_host;
                iss >> cfg.remote_port;
            }catch(int e){
                std::cout << "Error:" << e << std::endl;
            }
            // std::cout << cfg;
            pair.in = cfg;
            parse_flag = 2;
        }
        if(parse_flag==2 && s.find("out:") != std::string::npos){ // 解析out配置
            UdpConfig cfg;
            try{
                std::istringstream iss(s.substr(std::string("out:").length()));
                iss >> cfg.local_host;
                iss >> cfg.local_port;
                iss >> cfg.remote_host;
                iss >> cfg.remote_port;
            }catch(int e){
                std::cout << "Error:" << e << std::endl;
            }
            // std::cout << cfg;
            pair.out = cfg;

            parse_flag = 3;
        }

        if(parse_flag == 3){ // 创建UDP连接
            parse_flag = 0;
            pair.udp_in = std::make_shared<ConnUdp>(pair.in.local_host.c_str(), pair.in.local_port, pair.in.remote_host, pair.in.remote_port);
            pair.udp_out = std::make_shared<ConnUdp>(pair.out.local_host.c_str(), pair.out.local_port, pair.out.remote_host, pair.out.remote_port);
            cfg_list.emplace_back(pair);
        }
    }

    _fs.close();

}
void Proxy::add_connection(std::string host_in, uint16_t port_in, std::string host_out, uint16_t port_out){

}

std::ostream& operator <<(std::ostream &str, Proxy::UdpConfig const &cfg){
    std::cout << "[Udp config]: " << std::endl;
    std::cout << "  " << cfg.local_host << ":" << cfg.local_port << std::endl;
    std::cout << "  " << cfg.remote_host << ":" << cfg.remote_port << std::endl;
    return str;
}

}
